#include "mycanvas.h"
#include "primitive.h"

#include <GL/glut.h>

MyCanvas::MyCanvas(Scene *_scene) :
    modeling(_scene)
{
    this->scene = _scene;
    createCube();
    createPyramid();
}

void MyCanvas::createCube(){
    Object obj = modeling.factory.createObject();

    vector<Point> base;
    base.push_back(Point(-2.0, 0.1, 6.0));
    base.push_back(Point(-2.0, 0.1, 12.0));
    base.push_back(Point(-8.0, 0.1, 12.0));
    base.push_back(Point(-8.0, 0.1, 6.0));
    
    Face f = modeling.factory.createFace(base, obj.getId());
    obj.addFace(f);
    modeling.addObject(obj);
        
    modeling.createPrism(obj.getId(), f.getId(), Point(0.0, 6.0, 0.0));
}

void MyCanvas::createPyramid(){
    Object obj = modeling.factory.createObject();

    vector<Point> base;
    base.push_back(Point(-2.0, 0.1, -6.0));
    base.push_back(Point(-2.0, 0.1, -12.0));
    base.push_back(Point(-8.0, 0.1, -12.0));
    base.push_back(Point(-8.0, 0.1, -6.0));
    
    Face f = modeling.factory.createFace(base, obj.getId());
    obj.addFace(f);
    modeling.addObject(obj);
        
    modeling.createPyramid(obj.getId(), f.getId(), Point(0.0, 6.0, 0.0));
}

void MyCanvas::onMoveCursor(Cursor &cursor){
    printf("Pen: tx = %i\tty = %i\n",cursor.getTx(), cursor.getTy());
    this->scene->setRotateX( -cursor.getTy() );
    this->scene->setRotateZ( cursor.getTx() );
}


void MyCanvas::onPressKey(int key){

    switch(key){
        case KEY_8:
            if (this->scene->getRotateX() < 85.0)
                this->scene->setRotateX( this->scene->getRotateX()+0.8 );
            break;
        case KEY_2:
            if (this->scene->getRotateX() > -85.0)
                this->scene->setRotateX( this->scene->getRotateX()-0.8 );
            break;
        case KEY_4:
                this->scene->setRotateZ( this->scene->getRotateZ()-0.8 );
            break;
        case KEY_6:
                this->scene->setRotateZ( this->scene->getRotateZ()+0.8 );
            break;
    }
    printf("Key: tx = %f\tty = %f\n",this->scene->getRotateX(), this->scene->getRotateZ());
}

void MyCanvas::paint(void){
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glClearColor(0.80f, 0.80f, 0.80f, 1.0f );      

    glMatrixMode(GL_MODELVIEW); 
    glPushMatrix();
    
    glRotatef(this->scene->getRotateX(), 1.0, 0.0, 0.0);
    glRotatef(this->scene->getRotateY(), 0.0, 1.0, 0.0);   
    glRotatef(this->scene->getRotateZ(), 0.0, 0.0, 1.0);         

    modeling.updateScene(); 

    scene->drawEnviroment();
            
    Sphere s(Point(0.0, 4.0, 0.0), 4);
    glColor3f(1.0, 0.5, 0.5);
    s.draw();

    Cylinder c(Point(6.0, 4.0, 6.0), 3, Point(8.0, 0.0, -8.0));
    glColor3f(0.3, 0.7, 0.5);
    c.draw();
    
   
    
    glPopMatrix();

    glFlush();
}


void MyCanvas::initialize(){
    GLfloat  dimLight[] = { 0.1f, 0.1f, 0.1f, 1.0f };
    GLfloat  sourceLight[] = { 0.65f, 0.65f, 0.65f, 1.0f };
    GLfloat	 lightPos[] = { 0.0f, 0.0f, 0.0f, 1.0f };

    glEnable(GL_DEPTH_TEST);

    glEnable(GL_LIGHTING);

    glLightfv(GL_LIGHT0, GL_AMBIENT, dimLight);
    glLightfv(GL_LIGHT0,GL_DIFFUSE,sourceLight);
    glLightfv(GL_LIGHT0,GL_POSITION,lightPos);
    glEnable(GL_LIGHT0);

    glEnable(GL_COLOR_MATERIAL);
    glColorMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE);

    glClearColor(0.80f, 0.80f, 0.80f, 1.0f );
}


void MyCanvas::resizeCanvas(int _width, int _height){
    GLfloat fAspect;

    Viewport &viewport = this->scene->getViewport();
    Window &window = this->scene->getWindow();

    if (_width  == 0) _width  = 1;
    if (_height == 0) _height = 1;
    viewport.width = _width;
    viewport.height = _height;

    glViewport(viewport.left, viewport.top, viewport.width, viewport.height);

    fAspect = (GLfloat)_width/(GLfloat)_height;

    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();

    glOrtho(window.left, window.right, window.bottom, window.top, -10.0, 10.0);
    gluPerspective(20.0 , fAspect, -10.0, 30.0);
    gluLookAt(0.0, 25.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, -1.0);    

    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
}
